<?php

namespace App\Console\Commands;

use App\Enums\Field;
use App\Models\Library\UsedMaterials;
use Facebook\WebDriver\Remote\DesiredCapabilities;
use Facebook\WebDriver\Remote\RemoteWebDriver;
use Facebook\WebDriver\WebDriverBy;
use Facebook\WebDriver\WebDriverExpectedCondition;
use Facebook\WebDriver\WebDriverKeys;
use Illuminate\Console\Command;
use Illuminate\Support\Arr;

class CrawlerZhgCommand extends Command
{
    private string $serverUrl;

    private string $crawlerUrl;

    private string $containerXpathUrl;

    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'crawler:zhg {--all : 全量同步}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Command description';

    public function __construct()
    {
        parent::__construct();
        $this->serverUrl = 'http://localhost:4444';
        $this->crawlerUrl = 'https://zhg.cirs-group.com/product-and-service/china-cosmetic-ingredient';
        $this->containerXpathUrl = '//*[@id="__next"]/div[3]/div[1]/div[2]/div[1]/div/div/div';
    }

    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle()
    {
        $containerXpath = WebDriverBy::xpath($this->containerXpathUrl);
        $driver = RemoteWebDriver::create($this->serverUrl, DesiredCapabilities::chrome());
        $driver->get($this->crawlerUrl);
        foreach (Field::tmpCooliesArr as $tmpCookie) {
            $driver->manage()->addCookie($tmpCookie);
        }
        sleep(rand(1, 3));
        $driver->navigate()->refresh();
        sleep(rand(1, 3));
        $driver->wait()->until(WebDriverExpectedCondition::visibilityOfElementLocated($containerXpath));
        // 点击已知晓按钮
        $hasKnowCssSelector = "div.ant-modal-body > div.flex.justify-center> div > button";
        $driver->findElement(WebDriverBy::cssSelector($hasKnowCssSelector))->click();
        sleep(rand(1, 3));
        // 循环输入查询
        $query = UsedMaterials::query();
        if (!$this->option('all')) {
            $query = $query->where('is_processed', false);
        } else {
            $this->line('执行全量同步');
        }
        $totalCount = $query->count();
        $times = 0;
        $query->chunkById(20, function ($usedMaterials) use ($driver, $totalCount, &$times) {
            foreach ($usedMaterials as $usedMaterial) {
                $selectInputXpath = '//*[@id="__next"]/div[2]/div[3]/span/input';
                $selectButtonXpath = '//*[@id="__next"]/div[2]/div[3]/button';
                $selectInputElement = $driver->findElement(WebDriverBy::xpath($selectInputXpath));
                $selectInputElement->sendKeys($usedMaterial->name_zh);
                $driver->findElement(WebDriverBy::xpath($selectButtonXpath))->click();
                sleep(rand(1, 3));
                // 进入主流程
                $this->mainProcess($driver);
                // 清除数据
                $selectInputElement->sendKeys([WebDriverKeys::COMMAND, 'a']);
                $usedMaterial->update(['is_processed' => true]);
                sleep(rand(1, 3));
                $times++;
                $this->line('已成功查询第' . $times . '个数据，共' . $totalCount . '个数据。');
            }
        });
    }

    /**
     * 主爬取流程
     *
     * @param RemoteWebDriver $driver
     */
    public function mainProcess(RemoteWebDriver $driver)
    {
        // 主流程
        $containerXpath = WebDriverBy::xpath($this->containerXpathUrl);
        $containerItems = $driver->findElements($containerXpath);
        foreach ($containerItems as $key => $item) {
            $libraryName = Arr::first(explode("\n", $item->getText()));
//            $item->findElement(WebDriverBy::cssSelector("div>div"))->click();
            $itemClickElement = $item->findElement(WebDriverBy::cssSelector("div>div"));
            $driver->executeScript("arguments[0].click();", [$itemClickElement]);
            $detailItemsXpath = WebDriverBy::xpath($this->containerXpathUrl . '[' . ($key + 1) . ']/div[2]/div');
            foreach ($driver->findElements($detailItemsXpath) as $detailItem) {
                try {
                    $data = [];
                    $rawText = $detailItem->getText();
                    $rawTextArr = explode("\n", $rawText);
                    if (Arr::last($rawTextArr) == '详 情') {
                        $data['zhg_detail_path'] = $detailItem->findElement(WebDriverBy::cssSelector('a'))->getAttribute('href');
                        $rawTextArr = array_slice($rawTextArr, 0, -1);
                    }
                    foreach ($rawTextArr as $rawTextItem) {
                        $rawTextItemArr = explode(" ", $rawTextItem);
                        $keyNameZh = Arr::first($rawTextItemArr);
                        $value = implode('', array_slice($rawTextItemArr, 1));
                        $data[Field::usedMaterialFromZhgMappings[$keyNameZh]] = $value;
                    }
                    $data['is_updated'] = true;
                    $data['is_processed'] = true;
                    $targetCollect = app(Field::crawlerModelMappings[$libraryName])->where('name_zh', $data['name_zh'])->get();
                    if ($targetCollect->isNotEmpty()) {
                        $targetCollect->first()->update($data);
                    } else {
                        if (Field::crawlerModelMappings[$libraryName] == UsedMaterials::class) $data['sn'] = $data['zhg_sn'];
                        app(Field::crawlerModelMappings[$libraryName])->create($data);
                    }
                } catch (\Exception $exception) {
                    dd($exception->getMessage(), $data, $rawTextArr);
                }
            }
//            $this->line('跑完第' . $key + 1 . '大类，共' . count($containerItems) . '大类');
        }
    }
}
